import React, { useEffect, useRef, useState } from 'react';
import './conversation.less';
import { useDispatch, useSelector } from 'react-redux';

import { setIsConversation } from '@/redux/actions';
import { WebSocket } from '@/utils/webSocket';

interface RtcParams {
  fromUser: string;
  toUser: string;
  receiveVideo: HTMLVideoElement;
  localVideo: HTMLVideoElement;
  launch?: boolean;
}
class Rtc {
  fromUser: string;
  toUser: string;
  pc: RTCPeerConnection | undefined;
  receiveVideo: HTMLVideoElement;
  localVideo: HTMLVideoElement;
  launch: boolean;

  constructor(obj: RtcParams) {
    this.fromUser = obj.fromUser;
    this.toUser = obj.toUser;
    this.localVideo = obj.localVideo;
    this.receiveVideo = obj.receiveVideo;
    this.launch = obj.launch || false;
    this.init();
  }
  init() {
    this.createPC();
    this.onTrack();
    this.ICECandidateEvent();
    this.negotiationNeededEvent();
    this.onIceCandidate();
  }
  // 创建PC
  createPC() {
    const rtc = window.RTCPeerConnection || window.webkitRTCPeerConnection;
    this.pc = new rtc({
      iceServers: [
        // Information about ICE servers - Use your own!
        {
          urls: 'stun:stun1.l.google.com:19302',
        },
      ],
    });
  }
  // ICE候选触发
  ICECandidateEvent() {
    if (this.pc) {
      this.pc.onicecandidate = (event) => {
        console.log('发送iceCandidate');
        if (event.candidate) {
          WebSocket.socket.emit('iceCandidate', {
            type: 'new-ice-candidate',
            from: this.fromUser,
            to: this.toUser,
            candidate: event.candidate,
          });
        }
      };
    }
  }
  // onTrack事件
  onTrack() {
    if (this.pc) {
      let inboundStream: any = null;
      console.log('onTrack');
      this.pc.ontrack = (ev: RTCTrackEvent) => {
        if (ev.streams && ev.streams[0]) {
          console.log('支持track', ev);
          this.receiveVideo.srcObject = ev.streams[0];
          this.receiveVideo.onloadedmetadata = (e) => {
            console.log('播放了', e);
            this.receiveVideo.play();
          };
        } else {
          if (!inboundStream) {
            inboundStream = new MediaStream();
            this.receiveVideo.srcObject = inboundStream;
          }
          inboundStream.addstream(ev.track);
          console.log('支持addstream');
        }

        // if (ev.streams[0]) {
        //   this.receiveVideo.srcObject = ev.streams[0];
        // }
      };
    }
  }
  // 流媒体添加到本地调用
  negotiationNeededEvent() {
    if (this.pc) {
      this.pc.onnegotiationneeded = () => {
        console.log('触发列；拉屎大赛');
        (this.pc as RTCPeerConnection)
          .createOffer()
          .then((offer) => {
            if (this.pc) {
              return this.pc.setLocalDescription(offer);
            }
          })
          .then(() => {
            if (this.pc) {
              WebSocket.socket.emit('offer', {
                from: this.fromUser,
                to: this.toUser,
                type: 'video-offer',
                sdp: this.pc.localDescription,
              });
            }
          })
          .catch((err) => {
            console.error(err);
          });
      };
    }
  }
  // 接收ice候选
  onIceCandidate() {
    WebSocket.socket.on('iceCandidate', (data: any) => {
      console.log('接收ice', data);
      this.pc?.addIceCandidate(new RTCIceCandidate(data.candidate));
    });
  }
}

export default function Conversation() {
  const dispatch = useDispatch();
  const redux = useSelector((state: DefaultRedux) => state);
  const domVideo: any = useRef();
  const domOtherVideo: any = useRef();
  const page: any = useRef({
    stream: '',
  });

  const [isAnswer, setIsAnswer] = useState(false);

  // 挂断通话
  const hangUp = () => {
    dispatch(setIsConversation(false));
    if (page.current.stream) {
      page.current.stream.getTracks().forEach((track: any) => track.stop());
    }
  };
  // 接收通话
  const answer = () => {
    setIsAnswer(true);
  };

  useEffect(() => {
    // 如果是 真，说明是自己发起的通话
    if (redux.conversationOffer) {
      const pc = new Rtc({
        fromUser: redux.user.username,
        toUser: '2233299351@qq.com',
        receiveVideo: domOtherVideo.current,
        localVideo: domVideo.current,
        launch: true,
      });
      window.navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then((localStream) => {
        pc.localVideo.srcObject = localStream;

        pc.localVideo.onloadedmetadata = function (e) {
          pc.localVideo.play();
        };
        localStream.getTracks().forEach((track) => {
          pc.pc?.addTrack(track, localStream);
        });

        WebSocket.socket.on('answer', (data: any) => {
          console.log('调用者接收answer');
          pc.pc?.setRemoteDescription(data.sdp);
        });
      });
    } else {
      // 接收方
      WebSocket.socket.on('offer', (data: any) => {
        console.log('offer', data.sdp);
        const pc = new Rtc({
          fromUser: redux.user.username,
          toUser: data.from,
          localVideo: domVideo.current,
          receiveVideo: domOtherVideo.current,
        });
        pc.pc
          ?.setRemoteDescription(new RTCSessionDescription(data.sdp))
          .then(() => {
            return window.navigator.mediaDevices.getUserMedia({ video: false, audio: true });
          })
          .then((localStream) => {
            pc.localVideo.srcObject = localStream;
            pc.localVideo.onloadedmetadata = function (e) {
              pc.localVideo.play();
            };

            localStream.getTracks().forEach((track) => {
              pc.pc?.addTrack(track, localStream);
            });
          })
          .then(() => {
            return pc.pc?.createAnswer();
          })
          .then((answer) => {
            return answer && pc.pc?.setLocalDescription(answer);
          })
          .then(() => {
            WebSocket.socket.emit('answer', {
              from: pc?.fromUser,
              to: pc?.toUser,
              type: 'video-answer',
              sdp: pc.pc?.localDescription,
            });
          });
      });
    }
  }, []);

  return (
    <div className="Conversation">
      <video className="video" ref={domVideo} muted></video>

      {/* 对方通话的视频图像 */}
      <video className="other" ref={domOtherVideo}></video>
      {/*  */}
      {/* 操作按钮 */}
      {isAnswer || redux.conversationOffer ? (
        <footer className="footer fx fx-jc-c">
          <p className="hang-up fx-cc" onClick={hangUp}>
            挂断
          </p>
        </footer>
      ) : (
        <footer className="waiting">
          <p className="item red fx-cc">挂断</p>
          <p className="item blue fx-cc" onClick={answer}>
            接听
          </p>
        </footer>
      )}
    </div>
  );
}
